package com.haha.qqchannelbot.start;

import com.haha.qqchannelbot.config.GlobalConfig;
import com.haha.qqchannelbot.core.exception.MyRunTimeException;
import com.haha.qqchannelbot.entity.Bot;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.WebSocketConnectionManager;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * 启动机器人消息监听器
 */
@SpringBootApplication
@Log4j2
@Order(1)
public class BotChannel implements CommandLineRunner {

    @Value("${bot.base_url}")
    private String baseUrl;

    @Resource
    private BotSocketHandler botSocketHandler;

    private WebSocketConnectionManager manager;

    @Value("${bot.ws_url}")
    private String wsUrl;

    private WebSocketSession session;

    @Resource
    private Bot bot;

    @Override
    public void run(String... args) throws Exception {
        log.info("===============");
        log.info("机器人启动");
        initSocketConnection();
    }


    /**
     * 断开重连
     */
    public void reconnection() {
//        manager.stop();
        if (this.session != null && this.session.isOpen()) {
            try {
                this.session.close();
            } catch (IOException e) {
                log.error("关闭旧的WebSocket会话时出错", e);
            }
        }
        initSocketConnection();
        this.initSocketConnection();
    }

    /**
     * 初始化websocket连接
     */
    public void initSocketConnection() {
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("WebSocket-Reconnect-"));

        executor.execute(() -> {
            Integer reconnectCount = 0;
            while (reconnectCount < bot.getReconnectMax() && !GlobalConfig.shutDown.get()) {
                reconnectCount++;
                WebSocketClient client = new StandardWebSocketClient();
                try {
                    CompletableFuture<WebSocketSession> future = new CompletableFuture<>();
                    client.doHandshake(botSocketHandler, wsUrl).addCallback(
                            session -> {
                                log.info("WebSocket连接成功");
                                future.complete(session);
                            },
                            ex -> {
                                log.error("WebSocket连接失败", ex);
                                future.completeExceptionally(ex);
                            }
                    );
                    this.session = future.get();
                    bot.setSession(session);
                    break;
                } catch (Exception e) {
                    log.error("连接失败，等待{}秒后重连", bot.getReconnectInterval() / 1000, e);
                    Thread.currentThread().interrupt();
                    try {
                        TimeUnit.MILLISECONDS.sleep(bot.getReconnectInterval());
                    } catch (InterruptedException ex) {
                        log.error("线程被中断", ex);
                        Thread.currentThread().interrupt();
                        throw new MyRunTimeException(ex.getMessage());
                    }
                }
            }
        });
    }

//    /**
//     * 初始化websocket连接
//     */
//    public void initSocketConnection() {
//        WebSocketClient client = new StandardWebSocketClient();
//
//        String uri = baseUrl.replace("https", "wss") + "/websocket";
//        manager = new WebSocketConnectionManager(client, botSocketHandler, uri);
//        manager.start();
//    }
}
